﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Tycho.Parser.Peg;

namespace Tycho.Parser.Tests.Peg {
    [TestFixture]
    public class CompositeTermSpecification {
        [Test]
        public void AddSingleShouldAddTerm () {
            CompositeTerm term = new CompositeTerm ("name");

            IntegerTerm i = new IntegerTerm (1);
            term.Add ("a", i, false);

            Assert.AreSame (i, term.SubTerms["a"]);
        }

        [Test, ExpectedException (typeof (NamedRuleAlreadySetException))]
        public void AddSingleTwiceShouldThrowNamedRuleAlreadySetException () {
            CompositeTerm term = new CompositeTerm ("name");

            IntegerTerm i = new IntegerTerm (1);
            term.Add ("a", i, false);
            term.Add ("a", i, false);
        }

        [Test, ExpectedException (typeof (NamedListRuleAlreadySetException))]
        public void AddSingleThenAddMultipleShouldThrowNamedListRuleAlreadySetException () {
            CompositeTerm term = new CompositeTerm ("name");

            IntegerTerm i = new IntegerTerm (1);
            term.Add ("a", i, false);
            term.Add ("a", i, true);
        }

        [Test]
        public void AddMultipleShouldAddTermToList () {
            CompositeTerm term = new CompositeTerm ("name");

            IntegerTerm i = new IntegerTerm (1);
            term.Add ("a", i, true);

            Assert.IsTrue (term.SubTerms ["a"] is ListTerm);
            ListTerm listTerm = (ListTerm) term.SubTerms ["a"];
            Assert.AreEqual (1, listTerm.Terms.Count);
            Assert.AreSame (i, listTerm.Terms [0]);
        }

        [Test]
        public void AddMultipleShouldAddAllTermsToList () {
            CompositeTerm term = new CompositeTerm ("name");

            IntegerTerm i1 = new IntegerTerm (1);
            IntegerTerm i2 = new IntegerTerm (1);
            term.Add ("a", i1, true);
            term.Add ("a", i2, true);

            Assert.IsTrue (term.SubTerms ["a"] is ListTerm);
            ListTerm listTerm = (ListTerm) term.SubTerms ["a"];
            Assert.AreEqual (2, listTerm.Terms.Count);
            Assert.AreSame (i1, listTerm.Terms [0]);
            Assert.AreSame (i2, listTerm.Terms [1]);
        }
    }
}